package com.scalar.chiptrack.adaptor.vis;

import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.FabSortLot;
import com.scalar.chiptrack.adaptor.ShippedLot;
import com.scalar.chiptrack.adaptor.utils.ParserResult;
import com.scalar.chiptrack.adaptor.utils.Parser;
import com.scalar.chiptrack.adaptor.utils.ParserFactory;
import com.scalar.chiptrack.adaptor.utils.CSVParserImpl;
import com.scalar.chiptrack.adaptor.dao.FabSortAdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.ShippedLotDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.io.File;


/**
 * User: ChandraSekhar
 * Date: Jul 11, 2007
 * Time: 1:58:03 PM
 */
public class VISDataParser extends JobHandler implements AdaptorConstants
{
    private static Logger m_parserLogger    = null;
    private String m_dataOutputDir          = null;
    private HashMap<String, FabSortLot> m_fabWipDataMap   = new HashMap<String, FabSortLot>();
    private HashMap<String, ShippedLot> m_fabShipDataMap  = new HashMap<String, ShippedLot>();
    private HashMap<String, String> realTimeDataMap       = new HashMap<String, String>();

    public VISDataParser() throws ScalarException
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir( VENDOR_NAME_VIS, WIP_TYPE_FAB );
           
            if ( m_dataOutputDir != null )
            {
                AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );

                m_parserLogger = AdaptorUtils.getDataParserLogger( m_dataOutputDir,VENDOR_NAME_VIS );
                FabSortAdaptorDAO.setLogger( m_parserLogger );   // All the DAOs and Parser should be logging into same file
                ShippedLotDAO.setLogger( m_parserLogger );
                AdaptorUtils.setLogger( m_parserLogger );
            }
        }
        catch ( ScalarException se )
        {
            log( "ERROR!! ERROR!! ERROR!! Exception while loading VIS output/log directory details from database, Exception: " + se );
            throw se;
        }
    }
    /**
     *
     * @param args
     * @throws Exception
     */
    public static void main( String args[] ) throws Exception
    {
        new VISDataParser().execute();
    }

    /**
     *
     */
    public void execute() throws Exception
    {
        AdaptorUtils.printHeader( VENDOR_NAME_VIS, CONSTANT_PARSER );

        File doneDestDir = new File( m_dataOutputDir + "/done" );
        File dataoutDir  = new File( m_dataOutputDir );

        File[] fileList = dataoutDir.listFiles();

        if ( ( fileList == null ) || (fileList.length <= 3))
        {
            log("No file found in directory: " + dataoutDir);
            System.out.println("No file found in directory: " + dataoutDir );
            throw new ScalarException("No file found in directory: " + dataoutDir+ "----\n\n" );
        }

        ArrayList<File> successFileList   = new ArrayList<File>();

        boolean success             = false;
        for ( int i = 0; i < fileList.length; i++ )
        {
            try
            {
                if ( fileList[i].isDirectory() )
                {
                    continue;
                }

                if ( ( fileList[i].getName() != null ) && ( fileList[i].getName().trim().startsWith( VISAdaptor.FILE_NAME_WIP_STATUS ) ) )
                {

                    parseDailyWipReport( fileList[i].getAbsolutePath() );

                    successFileList.add( fileList[i] );
                }

                if ( ( fileList[i].getName() != null ) && ( fileList[i].getName().trim().startsWith( VISAdaptor.FILE_NAME_REAL_WIP_STATUS ) ) )
                {
                    parseRealTimeWipReport( fileList[i].getAbsolutePath() );

                    successFileList.add( fileList[i] );
                }

                if ( ( fileList[i].getName() != null ) && ( fileList[i].getName().trim().startsWith( VISAdaptor.FILE_NAME_SHIP_STATUS ) ) )
                {

                    parseShipmentReport( fileList[i].getAbsolutePath() );

                    //Add files to success list to move to /done directory
                    successFileList.add( fileList[i] );
                }
            }
            catch ( Exception e )
            {
                success = false;
                log( "ERROR!! ERROR!! ERROR!! While parsing and storing File:" + fileList[i].getAbsolutePath() + "\nException " + e );
                e.printStackTrace();
                throw e;
            }
        }

        // to save the Fab lot tables
        try
        {
            if ( m_fabWipDataMap.isEmpty() == false )
            {
                log( "Updating Fab Lot Information" );
                FabSortAdaptorDAO.saveFabLot( null, m_fabWipDataMap.values().iterator(), WIP_TYPE_FAB, VENDOR_NAME_VIS );
                success = true;
            }
            else
            {
                System.out.println( "This is FAB Data Parser FAB Part Number List is empty" );
                FabSortAdaptorDAO.closeFabSortLot( null, WIP_TYPE_FAB, VENDOR_NAME_VIS );
            }

        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! Could not update Fab Data information into database: " + e );
            e.printStackTrace();
            throw e;
        }

        try
        {
            // Save shipping info -
            if ( m_fabShipDataMap.isEmpty() == false )
            {
                log( "Updating shipment Information" );
                ShippedLotDAO.saveShippedLot( null, m_fabShipDataMap.values().iterator() );
                success = true;
            }
        }
        catch ( Exception e )
        {
            success = false;
            log( "ERROR!! ERROR!! ERROR!! Could not update VIS Shipping information into database: " + e );
            e.printStackTrace();
            throw e;
        }

        //Closing Previous DISCREPANCY LOTS, if the part number is Available at present
        AdaptorDAO.closeDropOutLots( VENDOR_NAME_VIS );

        // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
        AdaptorDAO.sendAllNotifications( VENDOR_NAME_VIS,true,true,true );


       int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( VISAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

        // Update Adaptor_Run_Info table
        try
        {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, VISAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
        }
        catch ( ScalarException se )
        {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, VISAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
        }

       // Step 7
       // Move the successful files to 'done' directory
       if ( success )
       {
           AdaptorUtils.moveFilesToDone( successFileList, doneDestDir );
       }
    }//end of execute method


    private void parseRealTimeWipReport( String fileName ) throws Exception
    {
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ParserResult result            = null;
        String lotNumber        = null;
        String vendorpartNo   = null;
        try
        {
            File fabWipFile = new File( fileName );
            if ( fabWipFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            log( "\nFound " + fileName );
            log( "\nParsing the file for Fab Real Time Wip Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "\nParsing the file for Fab Real Time Wip Report..." );
            Parser parser = ParserFactory.getCSVParser( fabWipFile, ',' );

            ((CSVParserImpl)parser).setHeaderRowIdx(0);
            ((CSVParserImpl)parser).setDataStartRowIdx(1);

            result = parser.parse();

            while ( result.next() )
            {
                lotNumber  = result.getString("Lot ID");
                vendorpartNo = result.getString("Current Mfg. Part");

                if ( vendorpartNo != null && vendorpartNo.trim().length() > 0 && lotNumber != null && lotNumber.trim().length() > 0 )
                {
                    if ( !realTimeDataMap.containsKey(vendorpartNo + lotNumber )  )
                    {
                        realTimeDataMap.put( vendorpartNo + lotNumber, result.getString("Wafer ID") );
                    }
                }//end of part number not null checking

            }
        }
        catch ( Exception ex )
        {   System.out.println("ERROR!!!ERROR!!! While Parsing the VIS Daily Real Time Wip Sheet");
            ex.printStackTrace();
            throw ex;
        }

    }
    private void parseDailyWipReport( String fileName ) throws Exception
    {
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ParserResult result            = null;
        FabSortLot fabSortLot   = null;
        String lotNumber        = null;
        String partNumber       = null;
        String vendorpartNo   = null;
        String waferId = null;
        try
        {
            File fabWipFile = new File( fileName );
            if ( fabWipFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            log( "\nFound " + fileName );
            log( "\nParsing the file for Fab Wip Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "\nParsing the file for Fab Wip Report..." );
            Parser parser = ParserFactory.getCSVParser( fabWipFile, ',' );

            ((CSVParserImpl)parser).setHeaderRowIdx(0);
            ((CSVParserImpl)parser).setDataStartRowIdx(1);

            result = parser.parse();

            while ( result.next() )
            {
                partNumber = result.getString("Customer Product");
                lotNumber  = result.getString("VIS Lot ID");
                vendorpartNo = result.getString("VIS Product");
                
                if ( partNumber != null && partNumber.trim().length() > 0 && lotNumber != null && lotNumber.trim().length() > 0
                        && result.getString("Current Stage") != null && !"Shipped".equalsIgnoreCase(result.getString("Current Stage").trim() ) )
                {

                    if( realTimeDataMap.containsKey( vendorpartNo + lotNumber ) )
                    {
                        waferId = realTimeDataMap.get( vendorpartNo + lotNumber );
                    }
                    else
                    {
                        waferId = null;
                    }
                     fabSortLot = m_fabWipDataMap.get( partNumber + lotNumber );
                     if ( fabSortLot == null )
                     {
                         fabSortLot = new FabSortLot( VENDOR_NAME_VIS, WIP_TYPE_FAB );
                         m_fabWipDataMap.put( partNumber + lotNumber , fabSortLot );
                     }

                     int quantity = 0;

                     if( fabSortLot.getQtyIn() != null )
                     {
                         try
                         {
                             quantity = Integer.parseInt( fabSortLot.getQtyIn() );
                         }
                         catch ( NumberFormatException ignore )
                         {
                         }
                         try
                         {
                             quantity += result.getInt("WIP Qty");
                         }
                         catch ( NumberFormatException ignore )
                         {
                         }
                     }
                     else
                     {
                         try
                         {
                             quantity = result.getInt("WIP Qty");
                         }
                         catch ( NumberFormatException ignore )
                         {
                         }
                     }

                     if ( quantity > 0 )
                     {
                         fabSortLot.setLotId( lotNumber );
                         fabSortLot.setCustProduct( partNumber );
                         fabSortLot.setFabLotNumber( lotNumber );
                         fabSortLot.setDateIn( result.getString("W/S Date") );
                         fabSortLot.setQtyIn( quantity +"");
                         fabSortLot.setStage( result.getString("Current Stage") );
                         fabSortLot.setStagePosition( result.getString("Stage No") );
                         fabSortLot.setLotCategory( LOT_CATEGORY_TYPE_PROD );
                         fabSortLot.setPoNumber( result.getString("Customer PO") );
                         fabSortLot.setWaferID( waferId );
                         fabSortLot.setLayer( result.getString("Layer No") );
                         fabSortLot.setLotCategory ( LOT_CATEGORY_TYPE_PROD );
                         if ( result.getString("Projected Date") != null && !"Customer Hold".equalsIgnoreCase( result.getString("Projected Date").trim() ) )
                         {
                            fabSortLot.setShip_fcst_date( result.getString("Projected Date") );
                            fabSortLot.setOutLookDate( result.getString("Projected Date") );
                         }
                         if ( result.getString("Committed Date") != null && !"Order Hold".equalsIgnoreCase( result.getString("Committed Date").trim() )  )
                         {
                            fabSortLot.setForcastedDateOut( result.getString("Committed Date") );    //Expected Date Out
                         }
                         fabSortLot.setFabId( result.getString("Fab") );
                         fabSortLot.setFabPartName ( vendorpartNo );
                         if ( result.getString("Mfg. Hold Flag") != null && "H".equalsIgnoreCase( result.getString("Mfg. Hold Flag").trim() ) )
                         {
                            fabSortLot.setLotStatus( LOT_STATUS_HOLD );
                         }
                         else
                         {
                            fabSortLot.setLotStatus( LOT_STATUS_RUNNING );
                         }
                     }
                }//end of part number not null checking

            }
        }
        catch ( Exception ex )
        {   System.out.println("ERROR!!!ERROR!!! While Parsing the VIS Daily wip Sheet");
            ex.printStackTrace();
            throw ex;
        }

    }

    /**
     *
     * @param fileName  parsedfile
     * @throws Exception  any exception
     */
    private void parseShipmentReport( String fileName ) throws Exception
    {

        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        ParserResult result     = null;
        ShippedLot shippedLot   = null;
        String lotNumber        = null;
        String partNumber       = null;
        String shipDate         = null;
        String nextLocation     = null;
        try
        {
            File detailShipFile = new File( fileName );
            if ( detailShipFile.exists() == false )
            {
                throw new ScalarException( fileName + " doesnt exist" );
            }

            log( "\nFound " + fileName );
            log( "\nParsing the file for Ship Report..." );
            System.out.println( "\nFound " + fileName );
            System.out.println( "\nParsing the file for Ship Report..." );

            Parser parser = ParserFactory.getCSVParser( detailShipFile, ',' );

            ((CSVParserImpl)parser).setHeaderRowIdx(0);
            ((CSVParserImpl)parser).setDataStartRowIdx(1);

            result = parser.parse();

            while ( result.next() )
            {
                partNumber = result.getString("Customer Product ID");
                lotNumber = result.getString("Lot ID");

                shipDate   =   result.getString("Invoice Date"); // giving as MM/dd/yyyy
                nextLocation = result.getString("Ship To");

                if ( partNumber != null && partNumber.trim().length() >0 && lotNumber != null && lotNumber.trim().length() > 0 )
                {
                    shippedLot = (ShippedLot) m_fabShipDataMap.get(partNumber + lotNumber + shipDate + nextLocation);
                    if (shippedLot == null)
                    {
                        shippedLot = new ShippedLot(VENDOR_NAME_VIS, LOCATION_TYPE_FAB );
                        m_fabShipDataMap.put(partNumber + lotNumber + shipDate+ nextLocation, shippedLot);
                    }

                    int quantity = 0;
                    if ( shippedLot.getShipQty() != null )
                    {
                       try
                       {
                           quantity = Integer.parseInt( shippedLot.getShipQty() );
                       }
                       catch ( NumberFormatException ignore )
                       {
                           quantity = 0;
                       }
                       try
                       {
                           quantity += result.getInt("Ship Qty");
                       }
                       catch ( NumberFormatException ignore )
                       {
                           quantity = 0;
                       }
                    }
                    else
                    {
                       try
                       {
                           quantity = result.getInt("Ship Qty");
                       }
                       catch ( NumberFormatException ignore )
                       {
                           quantity = 0;
                       }
                    }
                    String waferIds = null;
                   if ( shippedLot.getWaferID() != null )
                   {
                         waferIds =  shippedLot.getWaferID();

                        waferIds = waferIds + ";" + result.getString("Wafer ID");
                   }
                   else
                   {
                       waferIds = result.getString("Wafer ID");
                   }
                    if ( quantity > 0 )
                    {
                        shippedLot.setLotNumber( lotNumber );
                        shippedLot.setPartNumber( partNumber );
                        shippedLot.setShipDate( shipDate );
                        shippedLot.setShipQty( quantity + "");
                        shippedLot.setCustomerPO( result.getString("Customer PO") );
                        shippedLot.setInvoiceNumber( result.getString("Invoice Number") );
                        shippedLot.setNextLocation( nextLocation );
                        shippedLot.setFabLotNumber( lotNumber );
                        shippedLot.setProcessType( LOCATION_TYPE_FAB );
                        shippedLot.setWaferID( waferIds );

                    }
                }
            }
        }
        catch(Exception ex)
        {
            System.out.println("ERROR!!!ERROR!!! While Parsing the VIS Ship Report");
            ex.printStackTrace();
            throw ex;

        }
    }

    /**
     *
     * @param message
     */
    private static void log( String message )
    {

        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            synchronized ( m_parserLogger )
            {
                m_parserLogger.logDebug( message + LINE_SEPARATOR );
            }
        }
        else
        {
            System.out.println( message );
        }
    }

}
